package com.woniuxy.microcommonserver.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * JWT的工具类
 */
public class JWTUtil {
    /**
     * 签证中的私钥（盐值）
     * 去公司以后，woniuxy请修改了
     */
    public static final String SECURITY = "woniuxy";
    /**
     * 30分钟过期
     */
    private static int expiresAt = 30;
    /**
     * 创建令牌的方法
     * @param claims 自定义的载荷信息
     * @return Token令牌
     */
    public static String createToken(Map<String,Object> claims){
        //设置载荷
        PayLoad payLoad = createPayload();//产生标准载荷
        payLoad.setClaims(claims);//添加自定义的载荷信息
        //设置签证的加密处理
        Algorithm hmac256 = Algorithm.HMAC256(SECURITY);
        return createToken(payLoad,hmac256);
    }
    /** 根据载荷，以及签证进行Token令牌的产生
     * @param payLoad 载荷
     * @param hmac256 签证信息
     * @return
     */
    private static String createToken(PayLoad payLoad,Algorithm hmac256){
        //构建头（Header）
        JWTCreator.Builder builder = createHeader(hmac256);
        //构建标准载荷（PayLoad）
        buildStandardPayLoad(builder,payLoad);
        //构建自定义其他载荷信息（PayLoad）
        buildInitPayLoad(builder,payLoad);
        //根据签证，构建Token令牌
        return builder.sign(hmac256);
    }
    /**
     * 构建自定义其他载荷信息
     * @param builder
     * @param payLoad
     */
    private static void buildInitPayLoad(JWTCreator.Builder builder, PayLoad payLoad) {
        //获取 自定义的签名
        Map<String,Object> claims = payLoad.getClaims();
        if(claims != null && claims.size() > 0){
            // lambda 表达式的应用
            claims.forEach((k,v)->{
                builder.withClaim(k,(String) v);
            });
        }
    }
    /**
     * 构建标准载荷
     * @param builder
     * @param payLoad
     */
    private static void buildStandardPayLoad(JWTCreator.Builder builder, PayLoad payLoad) {
        // 构造签名者
        builder.withIssuer(payLoad.getIssuer());
        // 构造签名主题
        builder.withSubject(payLoad.getSubject());
        //设置签名时间（发令牌的时间）
        builder.withIssuedAt(payLoad.getIssuedAt());
        //设置过期时间
        builder.withExpiresAt(payLoad.getExpiresAt());
        //设置 令牌的接受者
        payLoad.getAudience().forEach((s)->{
            builder.withAudience(s);
        });
    }
    /**
     * 构建头
     * @param hmac256
     * @return
     */
    private static JWTCreator.Builder createHeader(Algorithm hmac256) {
        Map<String, Object> header = new HashMap<>();
        header.put("typ","JWT");
        header.put("alg",hmac256.getName());
        return JWT.create().withHeader(header);
    }
    /**
     * 设置标准载荷信息
     * @return
     */
    private static PayLoad createPayload(){
        PayLoad payLoad = new PayLoad();
        //设定令牌的发布者
        payLoad.setIssuer("j74");
        //设定Token令牌的主题
        payLoad.setSubject("stall");
        //设定哪些程序可以使用该令牌
        payLoad.setAudience("web","app","mapp");
        //设定令牌产生的时间
        Date date = new Date();
        payLoad.setIssuedAt(date);
        //设置过期时间
        payLoad.setExpiresAt(DateUtil.getAfterDate(date,expiresAt));
        return payLoad;
    }
}
